﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using PlaydeezGames.Common;

namespace IslandInterloper.Engine
{
    internal class Config : GameClient
    {
        private WeightedGenerator<string> vowelGenerator;
        public string GenerateVowel()
        {
            return vowelGenerator.Generate();
        }
        private WeightedGenerator<string> consonantGenerator;
        public string GenerateConsonant()
        {
            return consonantGenerator.Generate();
        }
        private WeightedGenerator<int> nameLengthGenerator;
        public int GenerateNameLength()
        {
            return nameLengthGenerator.Generate();
        }
        public string GenerateName()
        {
            string result = string.Empty;
            int nameLength = GenerateNameLength();
            bool vowel = RandomNumberGenerator.Current.Next(2) == 0;
            while (nameLength > 0)
            {
                if (vowel)
                {
                    result += GenerateVowel();
                }
                else
                {
                    result += GenerateConsonant();
                }
                vowel = !vowel;
                nameLength--;
            }
            return result.Substring(0,1).ToUpper()+result.Substring(1);
        }
        private int islandCount;
        public int IslandCount
        {
            get
            {
                return islandCount;
            }
        }
        private double minimumIslandX;
        public double MinimumIslandX
        {
            get
            {
                return minimumIslandX;
            }
        }
        private double minimumIslandY;
        public double MinimumIslandY
        {
            get { return minimumIslandY; }
        }
        private double maximumIslandX;
        public double MaximumIslandX { get { return maximumIslandX; } }
        private double maximumIslandY;
        public double MaximumIslandY { get { return maximumIslandY; } }
        public double GenerateIslandX()
        {
            return RandomNumberGenerator.Current.NextDouble() * (MaximumIslandX - MinimumIslandX) + MinimumIslandX;
        }
        public double GenerateIslandY()
        {
            return RandomNumberGenerator.Current.NextDouble() * (MaximumIslandY - MinimumIslandY) + MinimumIslandY;
        }
        private double minimumIslandDistance;
        public double MinimumIslandDistance { get { return minimumIslandDistance; } }
        private double maximumLocationDistance;
        public double MaximumLocationDistance { get { return maximumLocationDistance; } }
        private double maximumDockingDistance;
        public double MaximumDockingDistance { get { return maximumDockingDistance; } }
        private string currencyCommodity;
        public string CurrencyCommodity { get { return currencyCommodity; } }
        private string unknownIslandName;
        public string UnknownIslandName { get { return unknownIslandName; } }

        private int avatarStartDay;
        public int AvatarStartDay { get { return avatarStartDay; } }

        private string degreeSymbol;
        public string DegreeSymbol
        {
            get
            {
                return degreeSymbol;
            }
        }
        private string minuteSymbol;
        public string MinuteSymbol
        {
            get
            {
                return minuteSymbol;
            }
        }
        private string secondSymbol;
        public string SecondSymbol
        {
            get
            {
                return secondSymbol;
            }
        }

        private string startingIslandAnnotation;
        public string StartingIslandAnnotation
        {
            get
            {
                return startingIslandAnnotation;
            }
        }

        private int nullIslandId;
        public int NullIslandId
        {
            get
            {
                return nullIslandId;
            }
        }

        private double initialHeading;
        public double InitialHeading
        {
            get
            {
                return initialHeading;
            }
        }
        private string initialSpeed;
        public string InitialSpeed
        {
            get
            {
                return initialSpeed;
            }
        }
        private AvatarSpeeds avatarSpeeds;
        public AvatarSpeeds AvatarSpeeds
        {
            get
            {
                return avatarSpeeds;
            }
        }
        private string headingFormatString;
        public string HeadingFormatString
        {
            get
            {
                return headingFormatString;
            }
        }

        public string FormatHeading(IHeading heading,bool truncateSeconds)
        {
            if (heading == null) return string.Empty;
            return string.Format(HeadingFormatString,heading.WholeDegrees,degreeSymbol,heading.WholeMinutes,minuteSymbol,(truncateSeconds)?(heading.WholeSeconds):(heading.Seconds),secondSymbol);
        }
        internal Config(Game theGame, XElement element)
            : base(theGame)
        {
            FromXElement(element);
        }
        private void FromXElement(XElement element)
        {
            vowelGenerator = new WeightedGenerator<string>(element.Element(GameXNames.vowelGenerator),Utilities.FromStringToString);
            consonantGenerator = new WeightedGenerator<string>(element.Element(GameXNames.consonantGenerator), Utilities.FromStringToString);
            nameLengthGenerator = new WeightedGenerator<int>(element.Element(GameXNames.nameLengthGenerator), Utilities.FromStringToInt);
            islandCount = Utilities.XElementToInt(element.Element(GameXNames.islandCount));
            minimumIslandX = Utilities.XElementToInt(element.Element(GameXNames.minimumIslandX));
            minimumIslandY = Utilities.XElementToInt(element.Element(GameXNames.minimumIslandY));
            maximumIslandX = Utilities.XElementToInt(element.Element(GameXNames.maximumIslandX));
            maximumIslandY = Utilities.XElementToInt(element.Element(GameXNames.maximumIslandY));
            minimumIslandDistance = Utilities.XElementToDouble(element.Element(GameXNames.minimumIslandDistance));
            maximumLocationDistance = Utilities.XElementToDouble(element.Element(GameXNames.maximumLocationDistance));
            maximumDockingDistance = Utilities.XElementToDouble(element.Element(GameXNames.maximumDockingDistance));
            currencyCommodity = element.Element(GameXNames.currencyCommodity).Value;
            unknownIslandName = element.Element(GameXNames.unknownIslandName).Value;
            avatarStartDay = Utilities.XElementToInt(element.Element(GameXNames.avatarStartDay));
            degreeSymbol = element.Element(GameXNames.degreeSymbol).Value;
            minuteSymbol = element.Element(GameXNames.minuteSymbol).Value;
            secondSymbol = element.Element(GameXNames.secondSymbol).Value;
            startingIslandAnnotation = element.Element(GameXNames.startingIslandAnnotation).Value;
            nullIslandId = Utilities.XElementToInt(element.Element(GameXNames.nullIslandId));
            initialHeading = Utilities.XElementToDouble(element.Element(GameXNames.initialHeading));
            initialSpeed = element.Element(GameXNames.initialSpeed).Value;
            avatarSpeeds = new AvatarSpeeds(Game,element.Element(GameXNames.avatarSpeeds));
            headingFormatString = element.Element(GameXNames.headingFormat).Value;
        }
        public override XElement ToXElement(XName xName)
        {
            XElement result = new XElement(xName,
                vowelGenerator.ToXElement(GameXNames.vowelGenerator),
                consonantGenerator.ToXElement(GameXNames.consonantGenerator),
                nameLengthGenerator.ToXElement(GameXNames.nameLengthGenerator),
                new XElement(GameXNames.islandCount, islandCount.ToString()),
                new XElement(GameXNames.minimumIslandX, minimumIslandX.ToString()),
                new XElement(GameXNames.minimumIslandY, minimumIslandY.ToString()),
                new XElement(GameXNames.maximumIslandX, maximumIslandX.ToString()),
                new XElement(GameXNames.maximumIslandY, maximumIslandY.ToString()),
                new XElement(GameXNames.minimumIslandDistance, minimumIslandDistance.ToString()),
                new XElement(GameXNames.maximumLocationDistance, maximumLocationDistance.ToString()),
                new XElement(GameXNames.maximumDockingDistance, maximumDockingDistance.ToString()),
                new XElement(GameXNames.currencyCommodity, currencyCommodity),
                new XElement(GameXNames.unknownIslandName, unknownIslandName),
                new XElement(GameXNames.avatarStartDay, avatarStartDay),
                new XElement(GameXNames.degreeSymbol, degreeSymbol),
                new XElement(GameXNames.minuteSymbol, minuteSymbol),
                new XElement(GameXNames.secondSymbol, secondSymbol),
                new XElement(GameXNames.startingIslandAnnotation, startingIslandAnnotation),
                new XElement(GameXNames.nullIslandId, nullIslandId.ToString()),
                new XElement(GameXNames.initialHeading, initialHeading.ToString()),
                new XElement(GameXNames.initialSpeed,initialSpeed),
                avatarSpeeds.ToXElement(GameXNames.avatarSpeeds),
                new XElement(GameXNames.headingFormat,headingFormatString)
                );
            return result;
        }
    }
}
